<?php
namespace command\factory\config;

class ApiParse
{
    private $getMethod = ['list','info','find'];

    /**
     * 构建接口配置
     *
     * @param array $apiArr
     * @return void
     */
    public static function parse($apiArr,&$config)
    {
        $static = new static();

        $static->config = $config;

        $apiConf = [];

        foreach ($apiArr as $module => $setting) {
            $controller = [];
            $route = '';
            $api = [];
            foreach ($setting as $name => $methods) {
                $temp = $static->buildController($methods,$name);
                $controller[$temp['controller']['controller_name']]=$temp['controller'];
                $api = array_merge($api,$temp['api']);
                $route .= $temp['route'];
            }

            $apiConf[$module]=[
                'controller'=>$controller,
                'route'=>$route,
                'api'=>$api
            ];
        }

        $config['api']=$apiConf;

        return true;
    }

    /**
     * 解析构建控制器平台
     *
     * @param array $methods
     * @param string $name
     * @return void
     */
    private function buildController($methods,$name)
    {
        $nameInfo = explode('|',$name);

        $extInfo=[];
        foreach ($nameInfo as $key => $value) {
            if($key<2)continue;
            list($k,$v)=explode(':',$value);
            $extInfo[$k]=$v;
        }

        $controllerName = $nameInfo[0];
        $comment = $nameInfo[1];
        $api_cat = $extInfo['cat']??$comment;
        $except_token = $extInfo['ex_tok']??'';

        $methodList = [];
        $routeStr = "/**".($comment?:$controllerName)."*/".PHP_EOL;
        $api = [];
        foreach ($methods as $methodName => $mconfig) {
            $methodInfo = [];
            $this->parseMethodName($methodName,$methodInfo);
            $methodInfo['controller_name']=$controllerName;
            $serviceInfo = $this->config['service'][$methodInfo['call_logic']];
            $methodInfo['call_logic']=$serviceInfo['service_name'];
            if(is_array($mconfig)){
                $except = $mconfig['except']??[];
                $only = $mconfig['only']??[];
                foreach ($serviceInfo['methods'] as $mName => $mValue) {
                    if(!empty($except)&&in_array($mName,$except))continue;
                    if(!empty($only)&&!in_array($mName,$only))continue;

                    $tempInfo = $methodInfo;
                    $tempInfo['call_method']=$mName;
                    $this->buildMethod($tempInfo,$mconfig,$mValue,1);

                    $methodList[]=$tempInfo;
                    $routeStr .=$this->buildRoute($tempInfo['req_method'],$tempInfo['route'],$controllerName.'/'.$tempInfo['method_name'],$tempInfo['comment']);
                    if(in_array(strtolower($tempInfo['method_name']),explode(',',$except_token))){
                        $tempInfo['except_token']=1;
                    }
                    $api[]=['cate_name'=>$tempInfo['apicat']??$api_cat,'except_token'=>$tempInfo['except_token']??0,'title'=>$tempInfo['comment'],'path'=>$tempInfo['route'],'req'=>implode(',',$tempInfo['param']),'http_method'=>$tempInfo['req_method']];
                }
            }else{
                $this->buildMethod($methodInfo,$mconfig,$serviceInfo['methods'][$methodInfo['call_method']]);
                $methodList[]=$methodInfo;
                $routeStr .=$this->buildRoute($methodInfo['req_method'],$methodInfo['route'],$controllerName.'/'.$methodInfo['method_name'],$methodInfo['comment']);
                if(in_array(strtolower($methodInfo['method_name']),explode(',',$except_token))){
                    $methodInfo['except_token']=1;
                }
                $api[]=['cate_name'=>$methodInfo['apicat']??$api_cat,'except_token'=>$methodInfo['except_token']??0,'title'=>$methodInfo['comment'],'path'=>$methodInfo['route'],'req'=>implode(',',$methodInfo['param']),'http_method'=>$methodInfo['req_method']];
            }
        }

        $routeStr .= PHP_EOL;//拼接路由字符串

        $controller = [
            'comment'=>$comment,
            'controller_name'=>$controllerName,
            'api_cat'=>$api_cat,
            'except_token'=>$except_token,
            'methods'=>$methodList
        ];

        return ['controller'=>$controller,'route'=>$routeStr,'api'=>$api];
    }

    /**
     * 解析方法名信息
     *
     * @param string $name
     * @param array $methodInfo
     * @return void
     */
    private function parseMethodName($name,&$methodInfo)
    {
        $name = explode('|',$name);
        $methodInfo['method_name']=$name[0];
        $methodInfo['call_namespace']='app\\service';

        $call = explode('.',$name[1]);
        $methodInfo['call_logic']=$call[0];
        $methodInfo['call_method']=$call[1]??'';
        $methodInfo['comment']=$name[2]??'';

        return $this;
    }

    /**
     * 构建方法配置
     *
     * @param string $methodInfo
     * @param mixed $mconfig
     * @param array $serviceMethod
     * @param integer $cpname
     * @return void
     */
    private function buildMethod(&$methodInfo,$mconfig,$serviceMethod,$cpname=0)
    {
        if(is_array($mconfig)){
            $cusInfo = $mconfig['method'][$serviceMethod['method_name']]??'';
        }else{
            $cusInfo = $mconfig;
        }

        $cusInfo = explode('|',$cusInfo);
        $cusArr = [];
        foreach ($cusInfo as $value) {
            if(!$value)continue;
            list($k,$v)=explode(':',$value);
            $cusArr[$k]=$v;
        }

        if($cpname)$methodInfo['method_name'] = $serviceMethod['method_name'];
        $methodInfo['call_pk']=$serviceMethod['pk'];
        $methodInfo['call_type']=$serviceMethod['type'];
        $methodInfo['route'] = empty($cusArr['route'])?(($serviceMethod['alias_name']==$methodInfo['controller_name'])?'/'.$methodInfo['controller_name'].'/'.$serviceMethod['type']:'/'.$methodInfo['controller_name'].'/'.strtolower($methodInfo['method_name'])):$cusArr['route'];
        $methodInfo['req_method'] = in_array($serviceMethod['type'],$this->getMethod)?'get':'post';
        $methodInfo['param'] = empty($cusArr['param'])?$this->buildParam($serviceMethod,$cusArr['except']??'',$cusArr['append']??''):explode(',',str_replace("&","|",$cusArr['param']));

        if(empty($methodInfo['comment']))$methodInfo['comment']=$serviceMethod['comment'];
        if(!empty($cusArr['apicat']))$methodInfo['apicat']=$cusArr['apicat'];

        return $this;

    }

    /**
     * 构建请求参数
     *
     * @param array $serviceMethod
     * @param string $except
     * @param string $append
     * @return void
     */
    private function buildParam($serviceMethod,$except,$append)
    {
        switch ($serviceMethod['type']) {
            case 'add':
                $param = $serviceMethod['require'];
                break;
            case 'update':
                array_unshift($serviceMethod['allow_field']['param'],$serviceMethod['pk'].'|1|');
                $param = $serviceMethod['allow_field']['param'];
                break;
            case 'delete':
                $param = array($serviceMethod['pk'].'|1|');
                break;
            case 'list':
                $param = $serviceMethod['query']['param'];
                break;
            case 'find':
                $param = $serviceMethod['query']['param'];
                break;
            case 'info':
                $param = array($serviceMethod['pk'].'|1|');
                break;
            default:
                $param = '';
                break;
        }

        return $param;
    }

    /**
     * 构建路由字符串
     *
     * @param string $httpMethod
     * @param string $path
     * @param string $methodPath
     * @param string $comment
     * @return void
     */
    private function buildRoute($httpMethod,$path,$methodPath,$comment)
    {
        return "Route::".$httpMethod."(".$path.",'".$methodPath."');//".$comment.PHP_EOL;
    }

    

}